package by.gravity.drive_track.api;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;

import by.gravity.drive_track.fragments.RouteFragment;

import com.google.android.gms.maps.model.LatLng;

public class GoogleAPI implements GooleApiConstants {

	private static final String DIRECTION_URL = "http://maps.googleapis.com/maps/api/directions/json?%s&mode=%s&sensor=true";

	private static final String SEARCH_URL = "https://maps.googleapis.com/maps/api/place/textsearch/json?";

	private static HashMap<String, String> queryParams;

	/**
	 * First point on list is start point Second point on list is finish point
	 * Another is waypoints
	 */

	public static final String getDirectionRequest(List<LatLng> pointsList, RouteFragment.SELECTED_MODE selectedMode) {
		String mode;
		switch (selectedMode) {
		case CAR:
			mode = MODE_DRIVING;
			break;
		case WALK:
			mode = MODE_WALKING;
			break;

		default:
			mode = MODE_DRIVING;
			break;
		}
		return String.format(DIRECTION_URL, URLEncodedUtils.format(convertPoints(pointsList), UTF_8), mode);
	}

	public static final String getSearchPlacesRequest(String query) {
		addParam(QUERY, query);
		addParam(LANGUAGE, "ru");
		addParam(RANKBY, DESTINATION);
		return generateBaseMapsUrl(SEARCH_URL);
	}

	private static final BasicNameValuePair convertPointToBasicValuePair(String key, LatLng point) {
		return new BasicNameValuePair(key, convertPointToString(point));
	}

	private static final String convertPointToString(LatLng point) {
		return point.latitude + "," + point.longitude;
	}

	private static final List<BasicNameValuePair> convertPoints(List<LatLng> pointsList) {
		int sizeList = pointsList.size();
		List<BasicNameValuePair> result = new ArrayList<BasicNameValuePair>();
		if (sizeList >= 2) {
			result.add(convertPointToBasicValuePair(ORIGIN, pointsList.get(0)));
			result.add(convertPointToBasicValuePair(DESTINATION, pointsList.get(1)));
		}

		if (sizeList >= 3) {
			StringBuilder wayPoints = new StringBuilder(OPTIMIZE);
			for (int i = 2; i < pointsList.size(); i++) {
				wayPoints.append("|");
				wayPoints.append(convertPointToString(pointsList.get(i)));

			}

			result.add(new BasicNameValuePair(WAYPOINTS, wayPoints.toString()));
		}
		return result;
	}

	private static final void addParam(String key, String value) {
		if (queryParams == null) {
			queryParams = new HashMap<String, String>();
		}

		queryParams.put(key, value);
	}

	private static final String generateBaseMapsUrl(String url) {
		queryParams.put(SENSOR, "true");
		queryParams.put(KEY, API_KEY);
		return generateUrl(url, queryParams);
	}

	private static final String generateUrl(String url, HashMap<String, String> params) {
		StringBuilder builder = new StringBuilder(url);
		String[] keys = params.keySet().toArray(new String[] {});
		for (int i = 0, size = keys.length; i < size; i++) {
			try {
				String value = URLEncoder.encode(params.get(keys[i]), UTF_8);
				builder.append(keys[i] + "=" + value);
				if (i + 1 != size) {
					builder.append("&");
				}
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}

		}
		queryParams = null;
		return builder.toString();
	}

}
